package pc.nick.http;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class HttpServletRequest {

    /**
     * 请求方法
     */
    private String method;

    /**
     * 请求地址
     */
    private String requestURI;

    private String jsessionid = null;


    /**
     * 请求体
     */
    private String content;

    /**
     * 请求头
     */
    private Map<String,String> headers = new Hashtable<>();

    /**
     * 请求参数
     */
    private Map<String,String> parameters = new Hashtable<>();

    /**
     * 请求cookie信息
     */
    private List<Cookie> cookies = new ArrayList<>();

    public String getMethod() {
        return method;
    }

    public String getRequestURI() {
        return requestURI;
    }

    public Map<String,String> getHeaders() {
        return headers;
    }

    public String getHeader(String name){
        return headers.get(name);
    }

    public String getParameter(String key) {
        return parameters.get(key);
    }

    public List<Cookie> getCookies() {
        return cookies;
    }

    public String getJsessionid() {
        return jsessionid;
    }


    // 将输入流转换为String，开始解析
    public HttpServletRequest(InputStream iis) {
        // 一次性读完所有请求信息
        StringBuilder sb = new StringBuilder();
        int length = -1;
        byte[] bs = new byte[100*1024];

        try {
            length = iis.read(bs); // 读取socket输入流数据，将其放到byte数组里面
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("读取客户端请求异常");
        }

        // 将bs中字节数据转为char
        for (int i = 0; i < length; i++) {
            sb.append((char)bs[i]);
        }

        content = sb.toString(); // 将sb转为String，存到content里面
        parseProtocol(); // 开始解析
    }


    public HttpSession getSession(){
        HttpSession session;
        // 判断jsessionid是否存在，
        // 不存在，则创建一个httpSession存起来再返回
        if(jsessionid == null || !ServletContext.sessions.containsKey(jsessionid)){
              jsessionid = UUID.randomUUID().toString();
              session = new HttpSession(jsessionid);
              ServletContext.sessions.put(jsessionid,session);
        }else{
            // 存在则取出httpSession返回
            session = ServletContext.sessions.get(jsessionid);
        }
        return session;
    }

    /**
     * 解析协议
     */
    private void parseProtocol() {
        String[] ss = content.split(" ");
        // 解析 请求方法类型，存到method
        this.method = ss[0];

        // 解析 请求地址，存到requestURI
        this.requestURI = ss[1];

        // 解析 请求参数，存到parameters的map中
        parseParameter();

        // 解析 请求头，存到headers的map中
        parseHeader();

        // 解析 cookie: 从headers中获取cookie
        parseCookie();

        // 解析 sessionid: 从cookie中取出jsessionid
        jsessionid = parseJsessionid();


    }

    private String parseJsessionid() {
        if(cookies != null && cookies.size() > 0){
            for(Cookie c : cookies){
                if("JSESSIONID".equals(c.getName())){
                    return c.getValue();
                }
            }
        }
        return null;
    }

    /**
     * headers中取出cookie，然后再解析出cookie对象放入cookies中
     * 取出协议中的Cookie：xxxx，如果有则说明已经生成过Cookie，没有则表明是第一次请求，要生成Cookie编号
     */
    private void parseCookie() {
        if(headers == null && headers.size() <= 0){
            return;
        }
        // 从headers中取出键为cookie的值
        String cookieValue = headers.get("Cookie");
        if(cookieValue == null || cookieValue.length() <= 0){
            return;
        }
        String[] cvs = cookieValue.split(";");
        if(cvs.length > 0){
            for(String cv : cvs){
                String[] str = cv.split("=");
                if(str.length > 0){
                    String key = str[0];
                    String value = str[1];
                    Cookie cookie = new Cookie(key, value);
                    cookies.add(cookie);
                }
            }
        }
    }

    private void parseHeader() {
        // 请求头
        String[] parts = this.content.split("\r\n\r\n");
        //GET / HTTP/1.1
        String[] headerss = parts[0].split("\r\n");
        for(int i=1; i < headerss.length; i++){
            String[] headPair = headerss[i].split(": ");
            // Host: localhost    Connection: keep-alive
            headers.put(headPair[0], headPair[1]);
        }
    }

    private void parseParameter() {
        // requestURI: user.action?name=zhangsan&age=18
        int index = this.requestURI.indexOf("?");

        // 有?的话
        if(index >= 1){
            String[] pairs = this.requestURI.substring(index+1).split("&");
            for(String p : pairs){
                String[] po = p.split("=");
                parameters.put(po[0], po[1]);
            }
        }

        if(this.method.equals("POST")){
            String[] parts = this.content.split("\r\n\r\n");
            String entity = parts[1];
            String[] pairs = entity.split("&");
            for(String p : pairs){
                String[] po = p.split("=");
                parameters.put(po[0], po[1]);
            }
        }
    }
}
